{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "209cf49a",
   "metadata": {},
   "source": [
    "# NumPy 数据类型\n",
    "## Python 中的数据类型\n",
    "默认情况下，Python 拥有以下数据类型：\n",
    "\n",
    "strings - 用于表示文本数据，文本用引号引起来。例如 \"ABCD\"。\n",
    "\n",
    "integer - 用于表示整数。例如 -1, -2, -3。\n",
    "\n",
    "float - 用于表示实数。例如 1.2, 42.42。\n",
    "\n",
    "boolean - 用于表示 True 或 False。\n",
    "\n",
    "complex - 用于表示复平面中的数字。例如 1.0 + 2.0j，1.5 + 2.5j。\n",
    "\n",
    "## NumPy 中的数据类型\n",
    "NumPy 有一些额外的数据类型，并通过一个字符引用数据类型，例如 i 代表整数，u 代表无符号整数等。\n",
    "\n",
    "以下是 NumPy 中所有数据类型的列表以及用于表示它们的字符。\n",
    "\n",
    "i - 整数      b - 布尔        u - 无符号整数  f - 浮点\n",
    "\n",
    "c - 复合浮点数   m - timedelta    M - datetime    O - 对象\n",
    "\n",
    "S - 字符串     U - unicode 字符串  V - 固定的其他类型的内存块 ( void )"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bfdc39e9",
   "metadata": {},
   "source": [
    "## 检查数组的数据类型\n",
    "NumPy 数组对象有一个名为 dtype 的属性，该属性返回数组的数据类型："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "c322fa00",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "int32\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "arr = np.array([1, 2, 3, 4])\n",
    "\n",
    "print(arr.dtype)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "365cc1a1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<U6\n"
     ]
    }
   ],
   "source": [
    "arr = np.array(['apple', 'banana', 'cherry'])\n",
    "\n",
    "print(arr.dtype)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d5774730",
   "metadata": {},
   "source": [
    "## 用已定义的数据类型创建数组\n",
    "我们使用 array() 函数来创建数组，该函数可以使用可选参数：dtype，它允许我们定义数组元素的预期数据类型："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "529eb608",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[b'1' b'2' b'3' b'4']\n",
      "|S1\n"
     ]
    }
   ],
   "source": [
    "arr = np.array([1, 2, 3, 4], dtype='S')\n",
    "\n",
    "print(arr)\n",
    "print(arr.dtype)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "a92cd37b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 3 4]\n",
      "int32\n"
     ]
    }
   ],
   "source": [
    "# 创建数据类型为 4 字节整数的数组\n",
    "arr = np.array([1, 2, 3, 4], dtype='i4')\n",
    "\n",
    "print(arr)\n",
    "print(arr.dtype)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "30349ae2",
   "metadata": {},
   "source": [
    "## 假如值无法转换会怎样？\n",
    "如果给出了不能强制转换元素的类型，则 NumPy 将引发 ValueError。\n",
    "\n",
    "ValueError：在 Python 中，如果传递给函数的参数的类型是非预期或错误的，则会引发 ValueError。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "a5f63be3",
   "metadata": {},
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "invalid literal for int() with base 10: 'a'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-5-4101754d9810>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0marr\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0marray\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'a'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'2'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'3'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'i'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mValueError\u001b[0m: invalid literal for int() with base 10: 'a'"
     ]
    }
   ],
   "source": [
    "arr = np.array(['a', '2', '3'], dtype='i')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2c17cb85",
   "metadata": {},
   "source": [
    "## 转换已有数组的数据类型\n",
    "更改现有数组的数据类型的最佳方法，是使用 astype() 方法复制该数组。\n",
    "\n",
    "astype() 函数创建数组的副本，并允许您将数据类型指定为参数。\n",
    "\n",
    "数据类型可以使用字符串指定，例如 'f' 表示浮点数，'i' 表示整数等。或者您也可以直接使用数据类型，例如 float 表示浮点数，int 表示整数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "5e7447f0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 3]\n",
      "int32\n"
     ]
    }
   ],
   "source": [
    "# 通过使用 'i' 作为参数值，将数据类型从浮点数更改为整数\n",
    "arr = np.array([1.1, 2.1, 3.1])\n",
    "\n",
    "newarr = arr.astype('i')\n",
    "\n",
    "print(newarr)\n",
    "print(newarr.dtype)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "b3e8c79c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 3]\n",
      "int32\n"
     ]
    }
   ],
   "source": [
    "# 通过使用 int 作为参数值，将数据类型从浮点数更改为整数：\n",
    "arr = np.array([1.1, 2.1, 3.1])\n",
    "\n",
    "newarr = arr.astype(int)\n",
    "\n",
    "print(newarr)\n",
    "print(newarr.dtype)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "856a99a6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ True False  True]\n",
      "bool\n"
     ]
    }
   ],
   "source": [
    "# 将数据类型从整数更改为布尔值：\n",
    "arr = np.array([1, 0, 3])\n",
    "\n",
    "newarr = arr.astype(bool)\n",
    "\n",
    "print(newarr)\n",
    "print(newarr.dtype)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "09131531",
   "metadata": {},
   "source": [
    "# NumPy 数组副本 vs 视图\n",
    "## 副本和视图之间的区别\n",
    "副本和数组视图之间的主要区别在于副本是一个新数组，而这个视图只是原始数组的视图。\n",
    "\n",
    "副本拥有数据，对副本所做的任何更改都不会影响原始数组，对原始数组所做的任何更改也不会影响副本。\n",
    "\n",
    "视图不拥有数据，对视图所做的任何更改都会影响原始数组，而对原始数组所做的任何更改都会影响视图。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7441a69a",
   "metadata": {},
   "source": [
    "## 副本"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "eb72e135",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[61  2  3  4  5]\n",
      "[1 2 3 4 5]\n"
     ]
    }
   ],
   "source": [
    "arr = np.array([1, 2, 3, 4, 5])\n",
    "x = arr.copy()\n",
    "arr[0] = 61\n",
    "\n",
    "print(arr) \n",
    "print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1502074a",
   "metadata": {},
   "source": [
    "## 视图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "6a948a5d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[61  2  3  4  5]\n",
      "[61  2  3  4  5]\n"
     ]
    }
   ],
   "source": [
    "arr = np.array([1, 2, 3, 4, 5])\n",
    "x = arr.view()\n",
    "arr[0] = 61\n",
    "\n",
    "print(arr) \n",
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "1856a9b7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[31  2  3  4  5]\n",
      "[31  2  3  4  5]\n"
     ]
    }
   ],
   "source": [
    "arr = np.array([1, 2, 3, 4, 5])\n",
    "x = arr.view()\n",
    "x[0] = 31\n",
    "\n",
    "print(arr) \n",
    "print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a7e1a6d9",
   "metadata": {},
   "source": [
    "## 检查数组是否拥有数据\n",
    "如上所述，副本拥有数据，而视图不拥有数据，但是我们如何检查呢？\n",
    "\n",
    "每个 NumPy 数组都有一个属性 base，如果该数组拥有数据，则这个 base 属性返回 None。\n",
    "\n",
    "否则，base 属性将引用原始对象。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "aa79a945",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n",
      "[1 2 3 4 5]\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "arr = np.array([1, 2, 3, 4, 5])\n",
    "\n",
    "x = arr.copy()\n",
    "y = arr.view()\n",
    "\n",
    "print(x.base)\n",
    "print(y.base)\n",
    "print(arr.base)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.10"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
